/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package dungeonsolver.model;

import java.awt.Point;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Vector;

/**
 *
 * @author LegACy
 */
public class Labyrinth {
    public Labyrinth(String file) {
		//Initialize variable
		m_Width	    = 0;
		m_Height    = 0;
		m_Map	    = null;
		m_Exit	    = null;
		m_Entry	    = null;
		m_Buttons   = null;

		//Load file
		File TextFile = new File(file);

		try {
			//Initialize variable
			int X					= 0;
			int Y					= 0;
			Vector<Point> Buttons	= new Vector<Point>();

			//Create reader
			BufferedReader Reader   = new BufferedReader(new FileReader(TextFile));
			String Line				= Reader.readLine();

			//If first line exist
			if (Line != null) {
				//Create token
				String[] Tokens = Line.split(" ");
				if (Tokens.length != 2) return;

				//Set width and height
				m_Width	    = Integer.parseInt(Tokens[0]);
				m_Height    = Integer.parseInt(Tokens[1]);

				//Create map
				m_Map = new TileType[m_Width][m_Height];
				for (int x = 0; x < m_Width; x++)
					for (int y = 0; y < m_Height; y++)
						m_Map[x][y] = TileType.WALL;

				//Read next line
				Line = Reader.readLine();
			}

			//While line exist
			while (Line != null) {
				//Create tokens
				String[] Tokens = Line.split(" ");

				//For each token
				for (int i = 0; i < Tokens.length; i++) {
					//If x and y is within bound
					if (X >= 0 && X < m_Width && Y >= 0 && Y < m_Height) {
						//Set tile type
						if (Tokens[i].equals(TileType.PASSABLE.toString()))		m_Map[X][Y] = TileType.PASSABLE;
						else if(Tokens[i].equals(TileType.ENTRY.toString()))    m_Map[X][Y] = TileType.ENTRY;
						else if(Tokens[i].equals(TileType.EXIT.toString()))		m_Map[X][Y] = TileType.EXIT;
						else if(Tokens[i].equals(TileType.BUTTON.toString()))   m_Map[X][Y] = TileType.BUTTON;
						else if(Tokens[i].equals(TileType.WALL.toString()))		m_Map[X][Y] = TileType.WALL;
						
						//Check
						if (m_Map[X][Y] == TileType.EXIT)		m_Exit = new Point(X, Y);
						else if(m_Map[X][Y] == TileType.ENTRY)	m_Entry = new Point(X, Y);
						else if(m_Map[X][Y] == TileType.BUTTON)	Buttons.add(new Point(X, Y));
					}

					//Next
					X++;
				}

				//Set variable
				X = 0;
				Y++;
				
				//Read next line
				Line = Reader.readLine();
			}

			//Save button in array
			m_Buttons = new Point[Buttons.size()];
			for (int i = 0; i < Buttons.size(); i++) m_Buttons[i] = Buttons.elementAt(i);

			//Close reader
			if (Reader != null) Reader.close();
		} catch (Exception e) {}
    }

	public Point getEntry()		{	return  m_Entry;	}
	public Point getExit()		{	return  m_Exit;		}
	public Point[] getButtons()	{	return  m_Buttons;	}

	public boolean[][] getVisitMap() {
		//Create new array
		boolean[][] Map = new boolean[m_Width][m_Height];

		//For each cell
		for (int x = 0; x < m_Width; x++)
			for (int y = 0; y < m_Height; y++)
				Map[x][y] = m_Map[x][y] == TileType.WALL;

		//Return map
		return Map;
	}

	public Point[] getNeighbors(Point position) {
		if (position == null)	return new Point[0];
		else					return getNeighbors(position.x, position.y);
	}

        public int getWidth() {
            return this.m_Width;
        }

        public int getHeight() {
            return this.m_Height;
        }

	public Point[] getNeighbors(int x, int y) {
		//Create vector
		Vector<Point> Neighbors = new Vector<Point>();

		//Check 4 directions
		if (x > 0  && x < m_Width)		{ if (m_Map[x - 1][y	] != TileType.WALL) Neighbors.add(new Point(x - 1,	y	 )); }
		if (y > 0  && y < m_Height)		{ if (m_Map[x	 ][y - 1] != TileType.WALL) Neighbors.add(new Point(x,		y - 1)); }
		if (x >= 0 && x < m_Width - 1)	{ if (m_Map[x + 1][y	] != TileType.WALL) Neighbors.add(new Point(x + 1,	y	 )); }
		if (y >= 0 && y < m_Height - 1)	{ if (m_Map[x	 ][y + 1] != TileType.WALL) Neighbors.add(new Point(x,		y + 1)); }

		//Insert to array
		Point[] NeighborArray = new Point[Neighbors.size()];
		for (int i = 0; i < NeighborArray.length; i++) NeighborArray[i] = Neighbors.elementAt(i);

		//Return neighbors
		return NeighborArray;
	}

    //Type
    public enum TileType {
        PASSABLE    {@Override public String toString() { return "P"; }},
        ENTRY	    {@Override public String toString() { return "E"; }},
        EXIT	    {@Override public String toString() { return "X"; }},
        BUTTON	    {@Override public String toString() { return "B"; }},
        WALL	    {@Override public String toString() { return "W"; }}
    }

    //Map
    protected TileType[][]  m_Map;
    protected int           m_Width;
    protected int           m_Height;

    //Places of interest
    protected Point		m_Exit;
    protected Point		m_Entry;
    protected Point[]	m_Buttons;
}
